<?php
/**
 * Created by PhpStorm.
 * User: HanSon
 * Date: 2016/9/2
 * Time: 12:06
 */

namespace App\Service;


use App\Jobs\SaveBookSearch;
use Carbon\Carbon;
use Symfony\Component\DomCrawler\Crawler;
use WechatService as Wechat;
use GuzzleHttp\Client;

class LibraryService
{

    public $client;

    public $page;

    public $pageSize = 20;

    const PAGE_COUNT = 100;

    const LIBRARY_ID = 'gzpyp11111111';

    const HOME_URL = 'http://ngrok.zark.in:20075';

    const SEARCH_URL = 'http://weixin.zhaobenshu.com/WeiXin/scutgz/page/find/interface/find_ifp_findFullPage.php';

    const KEYWORD_URL = 'http://weixin.zhaobenshu.com/WeiXin/scutgz/page/find/interface/keyword_ifp_GetList.php?&y=1';

    //接口：库存
    const STOCK_URL = 'http://weixin.zhaobenshu.com/WeiXin/scutgz/page/find/interface/find_ifp_GetOpacColl.php'.'?ctrlNo=209726&openid=gzpyp11111111&y=1';

    //接口：书目藏馆
    const LOCATION_URL = 'http://weixin.zhaobenshu.com/WeiXin/scutgz/page/find/interface/find_ifp_GetSiteColl.php';

    //接口：书目详情
    const DETAIL_URL = 'http://weixin.zhaobenshu.com/WeiXin/scutgz/page/find/interface/find_ifp_GetDetail.php?ctrlRd=41ST9BU8GG&openid=gzpyp11111111&y=11&x=jQuery19109986680155712562_1473486205085&_=1473486205088';

    const BOOK_DETAIL_URL = 'http://ngrok.zark.in:20075/*/[barcode]/search';

    const READER_URL = 'http://ngrok.zark.in:20075/%b6%c1%d5%df%bf%e2/%5ball%5d/search';

    public function __construct()
    {
        $this->client = new Client();
    }

    /**
     * 图书搜索
     *
     * @param $keyword
     * @param int $page
     * @return array|bool|mixed|null|string
     */
    public function search($keyword, $page = 1)
    {
        $openId = \Auth::guard('wechat')->user()->open_id;
        if($page === 1)
            dispatch(new SaveBookSearch($openId, $keyword));

        $this->page = $page;

        $pageNo = $this->getPageNo();

        try{
            $response = $this->client->get(self::SEARCH_URL, [
                'query' => [
                    'openid' => self::LIBRARY_ID,
                    'keyword' => $keyword,
                    'pageNo' => $pageNo
                ]
            ]);
        }catch(\Exception $e){
            Wechat::report('图书搜索', $e);
            return false;
        }

        $content = $response->getBody()->getContents();

        $content = $this->handleBooks($content);

        return $content;
    }

    /**
     * 搜索结果处理
     *
     * @param $content
     * @return array|mixed|null|string
     */
    private function handleBooks($content)
    {
        $content = $this->removeBom($content);

        $content = json_decode(($content), true)['find_ifa_FindFullPage_list1'];

        if(!$content)
            return null;

        $content = $this->sliceBookResult($content);

        foreach ($content as &$book) {
            $detail = $this->getCover($book['CtrlRd']);
            $book['cover'] = $detail;
        }

        return $content;
    }

    /**
     * 获取转化后页数（因为接口一次查100条，吃不消，内部进行分页，20条一页）
     *
     * @return float
     */
    public function getPageNo()
    {
        $eachPage = self::PAGE_COUNT / $this->pageSize;

        return ceil($this->page / $eachPage);
    }

    /**
     * 分页
     *
     * @param $content
     * @return array
     */
    private function sliceBookResult($content)
    {
        $start = ($this->page - 1) * $this->pageSize;

        return array_slice($content, $start, $this->pageSize);
    }

    /**
     * 去除搜索时JSON奇葩的BOM
     *
     * @param $content
     * @return mixed|string
     */
    private function removeBom($content)
    {
        if (0 === strpos(bin2hex($content), 'efbbbf')) {
            $content = substr($content, 3);
        }

        return $content;
    }

    /**
     * 获取图书封面图
     * 
     * @param $ctrlRd
     * @return bool|null
     */
    private function getCover($ctrlRd)
    {
        try{
            $response = $this->client->get(self::DETAIL_URL, [
                'query' => [
                    'openid' => self::LIBRARY_ID,
                    'ctrlRd' => $ctrlRd,
                ]
            ]);
        }catch(\Exception $e){
            Wechat::report('图书详情(详情)', $e);
            return false;
        }

        $content = $response->getBody()->getContents();

        preg_match('/((http|https):\/\/)+(\w+\.)+(\w+)[\w\/\.\-]*(jpg|gif|png)/', $content, $match);

        if($match){
            return $match[0];
        }

        return null;
    }

    public function getLocation($ctrlRd, $ctrlNo)
    {
        try{
            $response = $this->client->get(self::LOCATION_URL, [
                'query' => [
                    'openid' => self::LIBRARY_ID,
                    'ctrlRd' => $ctrlRd,
                    'ctrlNo' => $ctrlNo,
                    'y'      => 11
                ]
            ]);
        }catch(\Exception $e){
            Wechat::report('图书位置', $e);
            return false;
        }

        $content = $response->getBody()->getContents();
        $content = $this->removeBom($content);

        $content = substr($content, 4, strlen($content) - 6);
        $content = json_decode($content, true);

        return $this->parseLocation($content);
    }

    private function parseLocation($content)
    {
        if(!isset($content['find_ifa_GetSiteColl_list1'][0])){
            return false;
        }
        $roomInfo = $content['find_ifa_GetSiteColl_list1'][0];

        $room = $roomInfo['Room2'] ? base64_decode($roomInfo['Room2']) : base64_decode($roomInfo['Room']);

        $floor = base64_decode($roomInfo['SiteL']);

        $detail = base64_decode($roomInfo['SitePJ']);

        $no = base64_decode($roomInfo['Callno']);

        $stock = $this->parseStock($content['find_ifa_GetSiteColl_list2']);

        return [
            'status' => 'success',
            'data' => [
                'room' => $room,
                'floor' => $floor,
                'detail' => $detail,
                'no' => $no,
                'stock' => $stock
            ]
        ];
    }

    private function parseStock($stocks)
    {
        $result = [];

        foreach ($stocks as $key => $stock) {
            $result[$key]['code'] = base64_decode($stock['Barcode']);
            $result[$key]['status'] = base64_decode($stock['Status']);
//            $result[$key]['status'] = str_replace('<br>', '', $result[$key]['status']);
        }

        return $result;
    }

    public function getReader($number)
    {
        $number = substr($number, 2);
        try{
            $response = $this->client->get(self::READER_URL, [
                'query' => [
                    'password' => $number,
                    'format' => 'detail',
                    'start' => '1',
                    'max' => '1',
                    'searchstyle' => 'normal',
                    'recordset' => 'marcrecord',
                    'word' => $number,
                ]
            ]);
        }catch(\Exception $e){
            Wechat::report('读者信息', $e);
            return false;
        }

        $content = $response->getBody()->getContents();

        $content = iconv('gb2312', 'utf-8', $content);

        $reader = $this->parseReader($content);

        return $reader;
    }

    private function parseReader($content)
    {
        $crawler = new Crawler();
        $crawler->addHTMLContent($content, 'UTF-8');
        $result = [];

        $crawler->filter('form[name="gisren"]')->filter('table tr')->each(function(Crawler $node, $i) use (&$result){

            if($i == 0) return null;

            $node->filter('td')->each(function(Crawler $node, $j) use (&$result, $i){
                if($j == 1){
                    $result[$i]['detail'] = $this->requestBookDetail($node->filter('a')->attr('href'));
                }elseif($j == 3){
                    $result[$i]['begin'] = $node->text();
                }elseif($j == 4){
                    $result[$i]['end'] = $node->text();
                }
            });
        });

        return $result;
    }

    private function requestBookDetail($query)
    {
        try{
            $response = $this->client->get(self::BOOK_DETAIL_URL . $query);
        }catch(\Exception $e){
            Wechat::report('图书详情', $e);
            return false;
        }

        $content = $response->getBody()->getContents();

        $content = iconv('gb2312', 'utf-8', $content);

        return $this->parseBookDetail($content);
    }

    private function parseBookDetail($content)
    {
        $crawler = new Crawler();

        $crawler->addHTMLContent($content, 'UTF-8');

        $infoDom = $crawler->filter('table[bgcolor="#ffffff"] tr');

        $detailDom = $infoDom->eq(2)->filter('td');

        $result['name'] = $detailDom->eq(1)->text();

        $result['author'] = $infoDom->eq(4)->filter('td')->eq(1)->text();

        $result['publish'] = $infoDom->eq('5')->filter('td')->eq(1)->text();

        return $result;
    }

    /**
     * 获取最晚还书时间
     *
     * @param $books
     * @return string
     */
    public function getLatestDate($books)
    {
        $date = Carbon::now();

        if($books){

            foreach ($books as $book) {
                $dt = Carbon::parse($this->getDate($book['end']));
                $date = $date->diffInDays($dt, false) > 0 ? $dt : $date;
            }

        }

        return $date->diffInDays(Carbon::now(), false) == 0 ? Carbon::now()->addMonth(2)->toDateString() : $date->toDateString();

    }

    public function isTodayExpire($book)
    {
        $end = $this->getDate($book['end']);

        if(Carbon::now()->diffInDays(Carbon::parse($end)) != 0){
            return false;
        }

        $book['date'] = $end;

        return $book;
    }

    private function getDate($date)
    {
        return substr($date, 0, 10);
    }
}